#include "serverrunner.h"
#include "serverclient.h"
#include "debug.h"

#include <string.h>
#include <algorithm>
#include <iostream>

#include <arpa/inet.h>
#include <unistd.h>

ServerRunner::ServerRunner(int serverFd) {
	pfds.push_back({ .fd = serverFd , .events = POLLIN }) ;
	memset( buffer , 0 , BUFSIZ + 4 ) ;
}

void ServerRunner::run() {
	std::cout << "server run. " << "fd: " << pfds[0].fd << "\n" ;
	while ( true ) {
		for ( auto &pfd : pfds ) 
			pfd.revents = 0 ;
		memset( buffer , 0 , BUFSIZ + 4 ) ;
		int count = poll( pfds.data() , pfds.size() , -1 ) ;

		for ( int i = 1 ; i < pfds.size() ; i++ ) {
			if ( pfds[i].revents & POLLIN ) {
				int len = read( pfds[i].fd , buffer , BUFSIZ ) ;
				buffer[len] = 0 ;
				if ( len < 1 ) {
					debug() << "disconnected for " 
							<< inet_ntoa( clients[pfds[i].fd]->getDetail().sin_addr ) 
							<< "\n" ;
					clients.erase( pfds[i].fd )  ;
					pfds.erase( pfds.begin() + i ) ;
					continue ;
				}
				buffer[len] = 0 ;
				debug() << "[command] :" << std::string( buffer ) << "\n" ;
				clients[ pfds[i].fd ]->runCommand(buffer) ;
			}
		}

		if ( pfds[0].revents & POLLIN ) {
			struct sockaddr_in  clientAddr ;
			memset( &clientAddr , 0 , sizeof(clientAddr) ) ;
			int alen = sizeof(clientAddr) ;
			int clientFd = accept( 
				pfds[0].fd , 
				(struct sockaddr*)&clientAddr ,
				(socklen_t*)&alen ) ;
			pfds.push_back( { .fd = clientFd , .events = POLLIN } ) ;
			clients[clientFd] = 
				std::move( 
					std::make_shared<ServerClient>( clientFd , clientAddr ) ) ;

			char *addrc = inet_ntoa( clientAddr.sin_addr ) ;
			debug() << "client address :" << std::string(addrc) << ":" 
					<< clientAddr.sin_port<< "\n"  ;
		}

	}
}

